package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.border.EtchedBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;

import dbConnection.Database;

public class Application {
    
    public static Database DB;
    
    //descriptions for prefabricated queries
    private static String[] queryDescriptions = {"Most Commonly Prescribed Drug",
	"Fetch <patient> vitals from <date>",
	"List drug interactions with <drug>",
	"Report patient smoker percentage",
	"What is <name> allergic to?",
	"How many people were diagnosed on <date>?",
	"What are the side effects of <Drug>?",
	"How many patients are allergic to <Drug>?",
	"How many patients have cancer diagnoses?",
	"Which patients take <Drug>?",
	"How many patients are diagnosed with more than one illness?",
	"How many smokers have lung cancer?",
	"What are <Person>'s current diagnoses?",
	"List male smokers taking <Drug>",
	"Which patients are over 113 kg?"};
    
    //Prefabricated queries
    private static String[] queries = {"SELECT name FROM \n(SELECT drugID, count(*) FROM PatientTakes GROUP BY drugID ORDER BY count(*) LIMIT 1) \nas temp, Drug \nWHERE temp.drugID = Drug.drugID;",
	"SELECT name, date, respirationRate, pulse, bloodPressure, weight, height FROM patient,vitals WHERE patient.PID = vitals.PID AND patient.name = '<PatientName>' AND date = '<YYYY-MM-DD>';",
	"SELECT distinct name from \n(select intdrugID from (select drugID2 as intdrugID from druginteraction,drug where drug.name = '<Drug Name>' and drug.drugID = druginteraction.drugID1) as bacon \nunion (select drugID1 as intdrugID from druginteraction,drug where drug.name = '<Drug Name>' and drug.drugID = druginteraction.drugID2)) as cheese \njoin drug on drug.drugID = cheese.intdrugID;",
	"SELECT (SELECT count(*) FROM Patient WHERE smoker = true)/count(*) FROM Patient;",
	"SELECT drug.name FROM PatientAllergies, Drug, Patient WHERE drug.drugID = PatientAllergies.drugID AND PatientAllergies.PID = Patient.PID AND patient.name = '<Patient Name>';",
	"SELECT count(*) FROM diagnosis WHERE date = '<YYYY-MM-DD>'",
	"SELECT sideEffects FROM Drug where name = '<Drug Name>';",
	"SELECT count(*) FROM patientallergies, drug WHERE patientallergies.drugID = drug.drugID AND drug.name = '<drug>'",
	"SELECT COUNT(*) FROM diagnosis WHERE diagnosisname LIKE 'cancer'",
	"SELECT patient.name FROM patient, patienttakes, drug WHERE Patient.PID = patienttakes.PID AND drug.drugID = patienttakes.drugID AND drug.name = '<Drug Name>'",
	"SELECT count(*) FROM (SELECT count(*) as count FROM diagnosis GROUP BY PID) diagCount WHERE count > 1",
	"SELECT count(*) from patient,diagnosis where patient.PID = diagnosis.PID and patient.smoker = 'true' and diagnosis.diagnosisname = 'lung cancer';",
	"SELECT diagnosisName from patient,diagnosis where patient.PID = diagnosis.PID and patient.name = '<Name>';",
	"SELECT patient.name from patient, patienttakes, drug where patient.PID = patienttakes.PID and \ndrug.drugID = patienttakes.drugID and patient.gender = 'male' and patient.smoker = true and drug.name = '<Drug>'",
	"select distinct patient.name from patient,vitals where vitals.weight > 113 and vitals.PID = patient.PID"};
   
    //defines whether a prefabricated query should be immediately run or requires user input
    private static boolean[] immediatelyExecute = {true,false,false,true,false,false,false,false,true,false,true,true,false,false,true};
    
    public static void main(String[] args) {
	DB = new Database();
    	
    	try {
    		DB.connect();
    	} catch (Exception e) {
    		e.printStackTrace();  // for now
    	}  
    	
    	final JFrame app = new JFrame("Healthcare Informatics: Raiders of the Lost Archives");
    	app.setLayout(new BorderLayout());
    	app.setPreferredSize(new Dimension(800,600));
    	
    	final ResultsPanel results = new ResultsPanel(DB);
    	
    	JPanel control = new JPanel();
    	control.setLayout(new BoxLayout(control, BoxLayout.Y_AXIS));
    	final JTextArea query = new JTextArea(); 
    	query.setLineWrap(true);
    	final JButton engage = new JButton("Engage");
    	final JTextArea cmdResult = new JTextArea();
    	
    	//first row
    	JPanel row1 = new JPanel();
    	row1.add(new JLabel("Query: "));
    	final JComboBox<String> prefabQueries = new JComboBox<String>(queryDescriptions);
    	prefabQueries.addActionListener(new ActionListener() {
    	    public void actionPerformed(ActionEvent e) {
    		query.setText(queries[prefabQueries.getSelectedIndex()].toLowerCase());
    		if (immediatelyExecute[prefabQueries.getSelectedIndex()]) {
    		    engage.doClick();
    		} else {
    		    //highlight information user needs to enter
    		    Matcher matcher = Pattern.compile("<.*?>").matcher(query.getText());
    		    cmdResult.setText("Please enter information");
    		    DefaultHighlighter.DefaultHighlightPainter highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
    		    while (matcher.find()) {
    			try {
			    query.getHighlighter().addHighlight(matcher.start(), matcher.end(), highlightPainter);
			} catch (BadLocationException e1) {
			    e1.printStackTrace();
			}
    		    }
    		}
    	    }
    	});
    	row1.add(prefabQueries);
    	final JComboBox<String> viewTable = new JComboBox<String>(DataGenerator.comboBoxFields);
    	viewTable.addActionListener(new ActionListener() {
    	    public void actionPerformed(ActionEvent e) {
    		query.setText("SELECT * FROM " + ((String)viewTable.getSelectedItem()).replaceAll("\\s", ""));
    		engage.doClick();
    	    }
    	});
    	row1.add(new JLabel(" View Table:"));
    	row1.add(viewTable);
    	control.add(row1);
    	
    	//second row
    	JPanel row2 = new JPanel();
    	row2.setLayout(new BoxLayout(row2, BoxLayout.X_AXIS));
    	query.setEditable(true);
    	query.setPreferredSize(new Dimension(700,100));
    	//query.getDocument().putProperty("filterNewlines", true);
    	query.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
    	query.setWrapStyleWord(true);
    	    	
    	engage.setMaximumSize(new Dimension(80,35));
    	row2.add(new JScrollPane(query));
    	row2.add(Box.createHorizontalStrut(10));
    	row2.add(engage);
    	control.add(row2);
    	
    	//third row
    	
    	cmdResult.setEditable(false);
    	cmdResult.setLineWrap(true);
    	cmdResult.setWrapStyleWord(true);
    	control.add(cmdResult);
    	
    	//action listeners
    	query.addKeyListener(new KeyListener() {
	    @Override
	    public void keyPressed(KeyEvent k) {
		if (k.getKeyCode() == KeyEvent.VK_ENTER) {
		    engage.doClick();
		}
	    }

	    @Override
	    public void keyReleased(KeyEvent arg0) {
		
	    }

	    @Override
	    public void keyTyped(KeyEvent arg0) {
		if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
		    engage.doClick();
		}
	    }
    	});
    	
    	engage.addActionListener(new ActionListener() {
    	    public void actionPerformed(ActionEvent e) {
    		if (query.getText().toLowerCase().contains("select")) {
    		    cmdResult.setText(results.sqlQuery(query.getText()));
    		} else {
    		    cmdResult.setText(results.sqlUpdate(query.getText()));
    		}
    	    }
    	});
    	
    	//build tabbed pane for random data generation
    	JTabbedPane tabs = new JTabbedPane();
    	tabs.addTab("Queries",control);
    	tabs.addTab("Generate Data", new DataGenerator(DB, results));
    	app.add(results, BorderLayout.CENTER);
    	app.add(tabs, BorderLayout.SOUTH);
    	app.pack();
    	app.setLocationRelativeTo(null);
    	app.setVisible(true);
    	app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	query.requestFocus();
    }
}
